package com.kitty.game.item.service;

import com.kitty.common.cache.entity.AppProperties;
import com.kitty.common.model.Reason;
import com.kitty.common.utils.SpringUtils;
import com.kitty.game.bag.message.RespIconCartoon;
import com.kitty.game.bag.message.RespStore;
import com.kitty.game.bag.model.StoreEquipInfo;
import com.kitty.game.base.service.BagService;
import com.kitty.game.config.ShapePen;
import com.kitty.game.config.SpecialItem;
import com.kitty.game.confirm.model.ShapePenConfirm;
import com.kitty.game.enter.FiedValue;
import com.kitty.game.enter.RespCardInfo;
import com.kitty.game.equip.message.RespNotifyMiscEx;
import com.kitty.game.equip.model.RoleEquip;
import com.kitty.game.equip.model.RoleEquipField;
import com.kitty.game.equip.service.EquipService;
import com.kitty.game.item.ItemDataPool;
import com.kitty.game.item.config.ChangeCard;
import com.kitty.game.item.message.RespRequestChangeLook;
import com.kitty.game.item.model.ToOtherChangeCard;
import com.kitty.game.onlinemall.service.MallService;
import com.kitty.game.role.model.Role;
import com.kitty.game.role.service.RoleService;
import com.kitty.game.task.service.taskHandler.ChangeCardTaskHandler;
import com.kitty.game.task.service.taskHandler.ShapePenTaskTaskHandler;
import com.kitty.game.team.message.RespConfirm;
import com.kitty.game.team.message.RespMsg;
import com.kitty.game.team.model.Team;
import com.kitty.game.team.service.TeamService;
import com.kitty.game.utils.Const;
import com.kitty.game.utils.FieldUtils;
import com.kitty.game.utils.TimeUtil;
import com.kitty.listener.EventType;
import com.kitty.listener.annotation.EventHandler;
import com.kitty.listener.event.LoginEvent;
import com.kitty.mina.cache.SessionUtils;
import com.kitty.mina.message.MessagePusher;
import org.apache.mina.core.session.IoSession;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.lang.Strings;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.MessageFormat;
import java.util.*;

/**
 * 变身卡
 */
@Service
public class ChangeCardService {

    @Resource
    private EquipService equipService;
    @Resource
    private MallService mallService;
    @Resource
    private BagService bagService;
    @Resource
    private RoleService roleService;


    @EventHandler(EventType.LOGIN)
    public void handleLoginEvent(LoginEvent loginEvent) {
        Role role = loginEvent.getRole();
        /**加载装备**/
        loadChangeCard(role);
    }

    /**
     * 加载变身卡
     */
    private void loadChangeCard(Role role) {
        RespCardInfo cardInfo = new RespCardInfo();
        cardInfo.setSize(role.getCardSize());
        MessagePusher.pushMessage(role, cardInfo);

        RespStore respStore = new RespStore();
        respStore.setStr("card_store");
        ArrayList<StoreEquipInfo> arrayList = new ArrayList<>();
        respStore.setList(arrayList);
        for (Map.Entry<Integer, RoleEquip> entry : role.getEquipBox().getEquips().entrySet()) {
            RoleEquip roleEquip = entry.getValue();
            if (roleEquip.getPosition() >= 2001 && roleEquip.getPosition() <= 2001 + role.getCardSize()) {
                StoreEquipInfo storeEquipInfo = new StoreEquipInfo();
                arrayList.add(storeEquipInfo);
                storeEquipInfo.setPos(roleEquip.getPosition());
                storeEquipInfo.setEquipFields(equipService.transferList(roleEquip.getFields()), equipService.transferList2(roleEquip.getHunQiFields()));
            }
        }
        MessagePusher.pushMessage(role, respStore);
    }

    /**
     * 初始化变身卡
     */
    public void init() {
        List<ChangeCard> cards = SpringUtils.getBean(Dao.class).query(ChangeCard.class, Cnd.NEW());
        Map<String,ChangeCard> name2ChangeCard = new HashMap<>(cards.size());
        cards.forEach(changeCard -> name2ChangeCard.put(changeCard.getName(), changeCard));
        ItemDataPool.name2ChangeCard = name2ChangeCard;

        //List<ShapePen> shapePens = SpringUtils.getBean(Dao.class).query(ShapePen.class, Cnd.NEW());
        List<ShapePen> shapePens = new ArrayList<>();
        {
            List<AppProperties> list = SpringUtils.getBean(Dao.class).query(AppProperties.class, Cnd.where("classtype","=","key2ShapePen").asc("id"));
            for (AppProperties appProperties : list) {
                ShapePen shapePen = new ShapePen();
                shapePen.setName(appProperties.getType_());
                shapePen.setIcon(Short.parseShort(appProperties.getValue_()));
                shapePen.setKeyName(appProperties.getKey_());
                shapePens.add(shapePen);
            }
        }
        Map<String, ShapePen> key2ShapePen = new HashMap<>(shapePens.size());
        shapePens.forEach(shapePen -> key2ShapePen.put(shapePen.getKeyName(), shapePen));
        ItemDataPool.key2ShapePen = key2ShapePen;
    }

    /**
     * 获得变身卡
     */
    public void getChangeCard(Role role, String name) {
        ChangeCard changeCard = ItemDataPool.name2ChangeCard.get(name);
        SpecialItem specialItem = mallService.getSpecialItem(name);
        if (changeCard == null || specialItem == null) {
            return;
        }
        RoleEquip roleEquip = new RoleEquip();
        roleEquip.setId(mallService.getRoleEquipId());
        roleEquip.setRoleId(role.getRoleId());
        roleEquip.setName(name);
        roleEquip.setFields(new LinkedHashMap<>());

        RoleEquipField roleEquipField = new RoleEquipField();
        roleEquipField.setType((short) 1);
        roleEquipField.setField(new LinkedHashMap<>());
        roleEquip.getFields().put(roleEquipField.getType(), roleEquipField);

        roleEquipField.getField().put((short) 306, new FiedValue(306, String.valueOf(roleEquip.getId())));
        roleEquipField.getField().put((short) 1, new FiedValue(1, name));
        roleEquipField.getField().put((short) 206, new FiedValue(206, 16758));
        roleEquipField.getField().put((short) 74, new FiedValue(74, 12));
        roleEquipField.getField().put((short) 84, new FiedValue(84, roleEquip.getId()));
        roleEquipField.getField().put((short) 40, new FiedValue(40, specialItem.getIcon()));

        roleEquip.setType("变身卡");
        equipService.add(role, roleEquip);
        saveCard(role, roleEquip);

        MessagePusher.pushMessage(role, new RespNotifyMiscEx("你获得了一张#R" + roleEquip.getName() + "#n。"));
        MessagePusher.pushMessage(role, new RespIconCartoon(roleEquip.getName()));
    }

    /**
     * 取空位
     */
    public short getStorePos(Role role) {
        short min = 2001, max = (short) (2001 + role.getCardSize());
        for (short i = min; i <= max; i++) {
            RoleEquip roleEquip = equipService.getRoleEquipByPos(role, i);
            if (roleEquip == null) {
                return i;
            }
        }
        return -1;
    }

    /**
     * 保存变身卡到卡套
     */
    public void saveCard(Role role, RoleEquip resultEquip) {
        /**变身卡位置从2001 开始 初始应该是15个 后面可以扩充 最大500个位置*/
        if (!resultEquip.getType().equals("变身卡")) {
            return;
        }
        short pos = getStorePos(role);
        if (pos <= 0) {
            return;
        }
        if (resultEquip.getPosition() != 0) {
            equipService.setPositionNull(role, resultEquip.getPosition());
        }
        resultEquip.setPosition(pos);
        RespStore respStore = new RespStore();
        respStore.setStr("card_store");
        ArrayList<StoreEquipInfo> arrayList = new ArrayList<>();
        respStore.setList(arrayList);
        StoreEquipInfo storeEquipInfo = new StoreEquipInfo();
        arrayList.add(storeEquipInfo);
        storeEquipInfo.setPos(resultEquip.getPosition());
        storeEquipInfo.setEquipFields(equipService.transferList(resultEquip.getFields()), equipService.transferList2(resultEquip.getHunQiFields()));
        MessagePusher.pushMessage(role, respStore);
    }


    /**
     * 取变身卡信息 clone
     */
    public ChangeCard getCardByName(String name) {
        ChangeCard changeCard = ItemDataPool.name2ChangeCard.get(name);
        try {
            changeCard = changeCard.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return changeCard;
    }


    /**
     * 整理到变身卡仓库的变身卡
     */
    public void sort(Role role, String toStoreCards) {
        if (Strings.isEmpty(toStoreCards)) {
            return;
        }
        String[] cardPosList = toStoreCards.split("\\|");
        for (String cardPos : cardPosList) {
            RoleEquip roleEquip = equipService.getRoleEquipByPos(role, Integer.parseInt(cardPos));
            if (!roleEquip.getType().equals("变身卡")) {
                continue;
            }
            equipService.setPositionNull(role, roleEquip.getPosition());
            short pos = getStorePos(role);
            roleEquip.setPosition(pos);
        }
        loadChangeCard(role);
    }

    /**
     * 消失在卡套的变身卡
     */
    public void sendNullPosition(Role role, short position) {
        ArrayList<StoreEquipInfo> storeEquipInfos = new ArrayList<>();
        StoreEquipInfo storeEquipInfo = new StoreEquipInfo();
        storeEquipInfo.setPos(position);
        storeEquipInfos.add(storeEquipInfo);
        RespStore respStore = new RespStore();
        respStore.setStr("card_store");
        respStore.setList(storeEquipInfos);
        MessagePusher.pushMessage(role, respStore);
    }

    /**
     * 增加卡套容量
     */
    public void addCardSize(Role role, short addSize) {
        /**一个格子需要12银元宝 银元宝不够可以用金元宝*/
        int needSilver = 12 * addSize;
        if (role.getSiver() < needSilver) {
            /**如果银元宝不足 但是加金元宝能购买*/
            if (role.getSiver() > 0 && (role.getGold() - role.getSiver()) >= needSilver) {
                String msg = "你花费了#R{0}#n个元宝（其中#R{1}#n以金元宝替代）购买了#R{2}#n个卡套空间。";
                int needGold = needSilver - role.getSiver();
                roleService.subtractSiver(role, role.getSiver(), Reason.ADD_CARD_SIZE);
                roleService.subtractGold(role, needGold, Reason.ADD_CARD_SIZE);
                MessagePusher.pushMessage(role, new RespNotifyMiscEx(MessageFormat.format(msg, needSilver, needGold, addSize)));
            } else if (role.getGold() < needSilver) {
                MessagePusher.pushMessage(role, new RespMsg("你的元宝不足。"));
                return;
            } else {
                /**金元宝足够*/
                String msg = "你花费了#R{0}#n个金元宝购买了#R{1}#n个卡套空间。";
                roleService.subtractGold(role, needSilver, Reason.ADD_CARD_SIZE);
                MessagePusher.pushMessage(role, new RespNotifyMiscEx(MessageFormat.format(msg, needSilver, addSize)));
            }
        } else {
            String msg = "你花费了#R{0}#n个元宝购买了#R{1}#n个卡套空间。";
            roleService.subtractSiver(role, needSilver, Reason.ADD_CARD_SIZE);
            MessagePusher.pushMessage(role, new RespNotifyMiscEx(MessageFormat.format(msg, needSilver, addSize)));
        }

        role.setCardSize((short) (role.getCardSize() + addSize));

        RespCardInfo cardInfo = new RespCardInfo();
        cardInfo.setSize(role.getCardSize());
        MessagePusher.pushMessage(role, cardInfo);
        role.save();
    }

    /**
     * 根据Icon取出变身卡
     */
    public ChangeCard getCardByIcon(int icon) {
        return ItemDataPool.name2ChangeCard.values().stream().filter(card -> card.getIcon() == icon).findFirst().orElse(null);
    }


    /**
     * 使用九曲玲珑笔
     */
    public void useShapePen(IoSession mySession, Role targetRole, String key, int pos) {
        Role role = SessionUtils.getRoleBySession(mySession);
        RoleEquip roleEquip = equipService.getRoleEquipByPos(role, pos);
        if (roleEquip == null) {//如果pos是0 找到的是空 在背包找第一个吧
            roleEquip = role.getEquipBox().getEquips().values().stream().
                    filter(equip -> equip.getName().equals("九曲玲珑笔")).
                    filter(equip -> equip.getPosition() > 40 && equip.getPosition() < 166).
                    findFirst().orElse(null);
        }
        ShapePen shapePen = getShapePen(key);
        if (roleEquip == null || (shapePen == null && !key.equals("hide_change_card"))) {
            return;
        }
        /**隐藏变身卡效果*/
        String tips;
        if (key.equals("hide_change_card")) {
            tips = "确认使用九曲玲珑笔#R隐藏变身卡#n形象？";
            shapePen = new ShapePen();
            shapePen.setIcon(targetRole.getRoleIcon());
            shapePen.setName("隐藏变身卡");
        } else {
            tips = MessageFormat.format("使用九曲玲珑笔将形象变为#R{0}#n，是否继续？", shapePen.getName());
        }

        if (role.getShapePen() != null) {
            tips = tips + "#r（使用后将#R覆盖#n原变身卡效果）";
        }
        if (role.equals(targetRole)) {
            role.setConfirm(new ShapePenConfirm(targetRole, shapePen, roleEquip));
            RespConfirm confirm = new RespConfirm();
            confirm.setTips(tips);
            MessagePusher.pushMessage(mySession, confirm);
        } else {
            targetRole.pushTempCache(Const.CHANGE_CARD, new ToOtherChangeCard(role, roleEquip, shapePen));
            MessagePusher.pushMessage(targetRole, new RespRequestChangeLook("#Y" + role.getName() + "#n对你使用#R" + roleEquip.getName().substring(0, roleEquip.getName().length() - 1) + "变身—" + shapePen.getName() + "#n，你确定要接受吗？"));
        }

    }

    /**
     * 取九曲玲珑笔变身的对象
     */
    private ShapePen getShapePen(String key) {
        ShapePen shapePen = ItemDataPool.key2ShapePen.get(key);
        if (shapePen == null) {
            return null;
        }
        return shapePen.clone();
    }

    public void useChangeCard(Role role, Role targetRole, RoleEquip roleEquip, ChangeCard changeCard) {
        SpringUtils.getEquipService().delRoleEquip(roleEquip, role);

        SpringUtils.getBean(ChangeCardService.class).sendNullPosition(role, roleEquip.getPosition());


        /**如果原本有变身卡任务 先删除*/
        SpringUtils.getBean(ChangeCardTaskHandler.class).delTask(targetRole);

        /**更新面板?*/
        setExpireTime(changeCard);
        targetRole.setChangeCard(changeCard);
        FieldUtils.sendChangeIcon(targetRole);

        /**发任务*/
        SpringUtils.getBean(ChangeCardTaskHandler.class).acceptTask(targetRole);

        /**更新外观*/
        SpringUtils.getBroadcastService().sendUpdateAppear(targetRole);

        /**发送增益属性*/
        SpringUtils.getRoleService().sendExtraAttribute(targetRole);

        /**广播特效*/
        SpringUtils.getBroadcastService().sendSoundEffect(targetRole);

        TeamService teamService = SpringUtils.getTeamService();
        Team team = teamService.getTeam(targetRole.getRoleId());
        if (team != null) {
            team.getList().forEach(member -> {
                if (member.getRoleId() == targetRole.getRoleId()) {
                    member.setCardName(changeCard.getName());
                }
            });
            teamService.updateTeamListEX(team);
            teamService.updateTeamList(targetRole);
        }
    }

    /**
     * 根据变身卡类型设置持续时间
     */
    private void setExpireTime(ChangeCard changeCard) {
        int type = changeCard.getType();
        long expireTime;
        if (type == 1) {//野怪的变身卡 12小时
            expireTime = TimeUtil.ONE_HOUR * 12;
        } else if (2 == type || type == 4) { //神兽 变异变身卡 6小时
            expireTime = TimeUtil.ONE_HOUR * 6;
        } else {//boss变身卡 8小时
            expireTime = TimeUtil.ONE_HOUR * 8;
        }
        changeCard.setExpireTime(System.currentTimeMillis() + expireTime);
    }

    public void useShapePen(Role role, Role targetRole, RoleEquip roleEquip, ShapePen shapePen) {
        /**减少九曲玲珑笔使用次数*/
        SpringUtils.getEquipService().subShapePenCount(role, roleEquip);
        /**如果原本有变身卡任务 先删除*/
        SpringUtils.getBean(ShapePenTaskTaskHandler.class).delTask(targetRole);

        shapePen.setExpireTime(Math.toIntExact((System.currentTimeMillis() + TimeUtil.ONE_HOUR * 4) / 1000));

        targetRole.setShapePen(shapePen);
        FieldUtils.sendChangeIcon(targetRole);

        /**发任务*/
        SpringUtils.getBean(ShapePenTaskTaskHandler.class).acceptTask(targetRole);

        /**更新外观*/
        SpringUtils.getBroadcastService().sendUpdateAppear(targetRole);

        /**刷新面板*/
        SpringUtils.getRoleService().sendExtraAttribute(targetRole);

        /**广播特效*/
        SpringUtils.getBroadcastService().sendSoundEffect(targetRole);
    }
}
